﻿// Copyright © 2011 Paul Vanukoff (pvanukoff@gmail.com)

using System;
using Bravura.Contracts.PluginTypes;
using Bravura.Core.PluginLib;
using Bravura.Native.PluginBase;

namespace Bravura.Native.Plugins.Filters
{
	/// <summary>
	/// A convolver.
	/// WORK IN PROGRESS
	/// </summary>
	public class Convolver : Filter, IFilter
	{
		#region Fields

		private int _bPos = 0;
		private int _bLen = 0;
		private double[] _buffer = null;

		private int _kLen = 0;
		private double[] _kernel = null;

		#endregion

		#region Properties

		#endregion

		public Convolver(IAudioPluginHost host, int sampleRate) : base(host, sampleRate)
		{
		}

		#region Open / Process / Close

		public override void Open()
		{
			_kLen = 6000;
			_kernel = new double[_kLen];

			for (int i = 0; i < _kLen; i++)
			{
				double v =  (double)(_kLen - i) / (double)_kLen;
				 _kernel[i] = 0.1 * v * v * (Utilities.Random.NextDouble() - 0.5);
			}

			_bLen = _kLen + 100;
			_buffer = new double[_bLen];
		}

		public override void Process(int count)
		{
			// read input buffer
			double[] ioBuff = GetInputBuffer(0).Read(count);

			// process
			for (int i = 0; i < count; i++)
			{
				double vIn = ioBuff[i];
				for (int k = 0; k < _kLen; k++)
				{
					int t = _bPos + k;
					if (t >= _bLen) t = t % _bLen;
					_buffer[t] += vIn * _kernel[k];
				}
				ioBuff[i] = _dryMix * vIn + _wetMix * _buffer[_bPos];
				_buffer[_bPos > 0 ? _bPos - 1 : _bLen - 1] = 0.0;
				_bPos = (_bPos + 1) % _bLen;
			}

			// write to output buffer
			GetOutputBuffer(0).Write(ioBuff, count);
		}

		public override void Close()
		{
			//
		}

		#endregion
	}
}
